<?php

namespace Muyuxuanpay\pay\logic;

use Muyuxuanpay\http\Http;
use Muyuxuanpay\pay\BasePay;
use Muyuxuanpay\tool\Mtool;

class FenFu extends BasePay
{
    protected $validateConfig = [
        'domain',
        'merchantNo',
        'secretKey',
        'business',
    ];

    public function pay($totalPrice,$paymentType,$orderNo,$noticeUrl="",$backUrl="",$goodsDesc='',$payTimeOut='',array $event=[]){
        if(!method_exists($this,$paymentType)){
            throw new \Exception("不支持的支付类型");
        }
        return $this->$paymentType($totalPrice,$orderNo,$noticeUrl,$backUrl,$goodsDesc,$payTimeOut,$event);
    }
    /**
     * 微信小程序支付
     * @param $totalPrice
     * @param $orderNo
     * @param $noticeUrl
     * @param $backUrl
     * @param $goodsDesc
     * @param $payTimeOut
     * @param array $event
     * @return false|null
     */
    public function wxmini($totalPrice,$orderNo,$noticeUrl="",$backUrl="",$goodsDesc="",$payTimeOut='',array $event=[]){
        return $this->wecate_pay($totalPrice,$orderNo,"wecate_mini",$noticeUrl,$backUrl,$goodsDesc,$payTimeOut,$event);
    }

    /**
     * 微信h5支付
     * @param $totalPrice
     * @param $orderNo
     * @param $noticeUrl
     * @param $backUrl
     * @param $goodsDesc
     * @param $payTimeOut
     * @param $event
     * @return array|false|null
     */
    public function wxh5($totalPrice,$orderNo,$noticeUrl="",$backUrl="",$goodsDesc='',$payTimeOut='',$event=[]){
        return $this->wecate_pay($totalPrice,$orderNo,"wecate_h5",$noticeUrl,$backUrl,$goodsDesc,$payTimeOut,$event);
    }

    /**
     * 微信支付
     * @param $totalPrice
     * @param $orderNo
     * @param $payType
     * @param $noticeUrl
     * @param $backUrl
     * @param $goodsDesc
     * @param $payTimeOut
     * @param $event
     * @return false|void
     */
    protected function wecate_pay($totalPrice,$orderNo,$payType,$noticeUrl="",$backUrl="",$goodsDesc='',$payTimeOut='',$event){
        if(!empty($this->validateConfig)){
            $res = $this->validate($this->validateConfig);
            if($res!==true){
                throw new \Exception($res);
//                $this->message = $res;
//                return false;
            }
        }
        $notice = $noticeUrl;
        if(empty($noticeUrl)){
            if(!empty($event['noticeUrl'])){
                $notice = $event['noticeUrl'];
            }else{
                if(!empty($this->config['noticeUrl'])){
                    $notice = $this->config['noticeUrl'];
                }
            }
        }
        if($payType=='wecate_mini'){
            $payType = "0";
        }elseif ($payType=='wecate_h5'){
            $payType = "3";
        }
        $arr = json_encode($goodsDesc);
        $goodsDesc = substr($arr,1,-1);
//        echo "<pre>";
//        print_r($goodsDesc);
//        exit;
        $newdata = [
            'requestType'=>empty($this->config['requestType'])?'IOZ1004':$this->config['requestType'],
            'requestId'=>$orderNo,
            'requestStartTime'=>date("YmdHis"),
            'merchantCode'=>$this->config['merchantNo'],
            'totalBizType'=>$this->config['business'],
            'totalPrice'=>strval($totalPrice),
            'goodsDesc'=>$goodsDesc,
            'envFlag'=>$payType,
            'rePayTimeOut'=>0,
            'noticeUrl'=>$notice,
            'backUrl'=>$backUrl,
            'passThrough'=>'order_img',
            'terminalIp'=>empty($event['ip'])?'127.0.0.1':$event['ip'],
        ];
//        echo "<pre>";
//        print_r($newdata);
//        exit;
        if(!empty($event)){
            if(empty($event['bizType'])){
                $newdata['bizType'] = $this->config['business'];
            }
            $newdata = array_merge($event,$newdata);
        }
        $order = [
            'requestType',
            'requestId',
            'merchantCode',
            'totalBizType',
            'totalPrice',
            'goodsDesc',
            'envFlag',
            'rePayTimeOut',
            'noticeUrl',
            'backUrl',
            'passThrough',
        ];
        $this->log([
            "签名前",
            $newdata
        ]);
        $newdata['signature'] = $this->getSign($newdata,$order);
        //签名失败
        if($newdata['signature']===false){
            throw new \Exception("签名失败");
//            return false;
        }
        $this->log([
            "签名后",
            $newdata
        ]);
        $back = $this->request('/wechatTransitGateway/merchant.do',$newdata);
        $this->log([
            "返回",
            $back
        ]);
        //请求失败
        if($back===false){
            throw new \Exception("请求失败");
//            return false;
        }
        if(!empty($back['errorMsg'])||!empty($back['errorCode'])){
            $this->message = $back['errorMsg'];
            if(!empty($this->errorMessage[$back['result']])){
                $this->message = $this->errorMessage[$back['result']];
            }
            throw new \Exception($this->message);
//            return false;
        }
        if(isset($back['result'])&&$back['result']!='00000'){
            if(!empty($back['errorMsg'])){
                $this->message = $back['errorMsg'];
            }
            if(!empty($this->errorMessage[$back['result']])){
                $this->message = $this->errorMessage[$back['result']];
            }
            throw new \Exception($this->message);
//            return false;
        }
        if($payType=='0'){
            $pay_type = 3;
            $response = [
                'pay_type'=>$pay_type,//1=官方数据包支付,2=跳转H5支付,3=跳转微信小程序支付,4=跳转支付宝小程序支付
                'resource'=>$back,//数据包
                'app_id'=>$back['mpAppId'],
                'mini_path'=>$back['mpPath']
            ];
        }elseif ($payType=='3'){
            $pay_type = 2;
            $response = [
                'pay_type'=>$pay_type,//1=官方数据包支付,2=跳转H5支付,3=跳转微信小程序支付,4=跳转支付宝小程序支付
                'resource'=>$back,//数据包
                'url'=>$back['payUrl']
            ];
        }
        return $response;
    }

    /**
     * 获取签名
     * @param $data
     * @param array $order
     * @return false|string
     */
    protected function getSign($data,array $order){
        try {
            $str = "";
            foreach ($order as $v){
                if(isset($data[$v])){
                    $str .= $data[$v];
                }
            }
//            echo "<pre>";
//            print_r($str);
//            exit;
            $str = hash_hmac('md5',$str,$this->config['secretKey']);
        }catch (\Exception $e){
            $this->message = $e->getMessage();
            return false;
        }
        return $str;
    }

    /**
     * 上游请求
     * @param $data
     * @return false|mixed
     */
    protected function request($url,$data){
        $url = $this->config['domain'].$url;
        $response = Http::post($url,$data,[
            CURLOPT_HTTPHEADER=>[
                'Accept: application/json'
            ],
            CURLOPT_HEADER=>false
        ]);
        try {
            $response = mb_convert_encoding($response, 'UTF-8', 'GBK');
            $response = json_decode($response,true);
        }catch (\Exception $e){
            throw new \Exception($e->getMessage());
        }
        return $response;
    }
    public function QueryOrderNo(?string $orderNo)
    {

        $url = "/main/SearchOrderAction_merSingleQuery";
        if(empty($orderNo)){
            throw new \Exception("订单号不能为空");
//            $this->message = "订单号不能为空";
//            return false;
        }
        $newdata = [
            'requestId'=>Mtool::getOrderNum(18),
            'requestStartTime'=>date("YmdHis"),
            'merchantCode'=>$this->config['merchantNo'],
            'originalRequestId'=>$orderNo,
        ];
        $order = [
            'requestId',
            'merchantCode',
            'originalRequestId',
        ];
        $this->log([
            "签名前",
            $newdata
        ]);
        $newdata['signature'] = $this->getSign($newdata,$order);
        $this->log([
            "签名后",
            $newdata
        ]);
        $back = $this->request($url,$newdata);
        $this->log([
            "返回",
            $back
        ]);
        if(isset($back['result'])&&$back['result']!='00000'){
            if(!empty($back['errorMsg'])){
                $this->message = $back['errorMsg'];
            }
            if(!empty($this->errorMessage[$back['result']])){
                $this->message = $this->errorMessage[$back['result']];
            }
            throw new \Exception($this->message);
//            return false;
        }
        $response = [
            'status'=>$back['status']==2?1:0,
            'orderNo'=>$back['originalRequestId'],
            'flowing_water'=>$back['tradeId'],
            'pay_time'=>$back['endTime']
        ];
        return $response;
    }
    public function RefundOrderNo(?string $orderNo,?string $refundNo,$allPrice,$refundPrice,$noticeUrl='',string $refundReason='',array $event=[]){
        $url = "/main/Refund_do";
        if(empty($orderNo)){
            throw new \Exception("订单号不能为空");
//            $this->message = "订单号不能为空";
//            return false;
        }
        if(empty($refundNo)){
            throw new \Exception("退款单号不能为空");
//            $this->message = "退款单号不能为空";
//            return false;
        }
        if(empty($refundPrice)){
            $this->message = "退款金额不能为空";
            throw new \Exception($this->message);
//            return false;
        }
        $newdata = [
            'requestId'=>$refundNo,
            'originalRequestId'=>$orderNo,
            'requestStartTime'=>date("YmdHis"),
            'tradeProcess'=>$this->config['merchantNo'],
            'fund'=>$refundPrice,
            'noticeUrl'=>$noticeUrl,
            'reason'=>$refundReason,
            'refundMothed'=>'1',
            'remark'=>''
        ];
        $this->log([
            "签名前",
            $newdata
        ]);
        $order = [
            'requestId',
            'originalRequestId',
            'tradeProcess',
            'fund',
            'noticeUrl',
        ];
        $newdata['mersignature'] = $this->getSign($newdata,$order);
        $this->log([
            "签名后",
            $newdata
        ]);
        $back = $this->request($url,$newdata);
        $this->log([
            "返回",
            $back
        ]);
        if(!empty($back['errorMsg'])||!empty($back['errorCode'])){
            $this->message = $back['errorMsg'];
            if(!empty($this->errorMessage[$back['result']])){
                $this->message = $this->errorMessage[$back['result']];
            }
            throw new \Exception($this->message);
//            return false;
        }
        if(isset($back['result'])&&$back['result']!='00000'){
            if(!empty($back['errorMsg'])){
                $this->message = $back['errorMsg'];
            }
            if(!empty($this->errorMessage[$back['result']])){
                $this->message = $this->errorMessage[$back['result']];
            }
            throw new \Exception($this->message);
//            return false;
        }
        $this->message = "申请退款成功";
        return $refundNo;
    }
}